package cn.egame.extraction.multithread.file;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import cn.egame.common.exception.ExceptionCommonBase;
import cn.egame.common.util.Utils;
import cn.egame.extraction.multithread.pojo.EfsInfo;
import cn.egame.extraction.multithread.util.ConstVar_EFS;
import cn.egame.extraction.multithread.util.EnumType_EFS.EfsInfoFromType;
import cn.egame.extraction.multithread.util.EnumType_EFS.InputErrorFileAppendType;
import cn.egame.extraction.multithread.util.Util;
import cn.egame.interfaces.fl.FileUsedType;
import cn.egame.interfaces.fl.FileUtils;

public class FileService {

	private static Logger logger = Logger.getLogger(FileService.class);
	private static byte[] lock = new byte[0];
	
	public long getMaxId(String filePath) throws ExceptionCommonBase{
		synchronized (lock) {
			long readMaxId = 0;
			File file = new File(filePath);
			if(!file.exists()){
				throw new ExceptionCommonBase(-1, "存储最大id的文件");
			}
			
			BufferedReader br = null;
			try {
				br = new BufferedReader(new InputStreamReader(
						new FileInputStream(file),"utf-8"));
				readMaxId = new Long(br.readLine());
			} catch (Exception e) {
				logger.error(e);
				throw new ExceptionCommonBase(-1, "从文件中读取id失败");
			} finally{
				if(br!=null){
					try {
						br.close();
					} catch (IOException e) {
						logger.error(e);
						throw ExceptionCommonBase.throwExceptionCommonBase(e);
					}
				}
			}
			if(readMaxId==0L){
				throw new ExceptionCommonBase(-1, "文件中id为0");
			}
			return readMaxId;
		}
	}
	
	public void setMaxId(long id, String filePath) throws ExceptionCommonBase{
		synchronized (lock) {
			try {
				Thread.sleep(200);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
				throw ExceptionCommonBase.throwExceptionCommonBase(e1);
			}
			PrintWriter pw = null;
			try {
				pw = new PrintWriter(new OutputStreamWriter(
						new FileOutputStream(filePath),"utf-8"), false);
					pw.println(id);
			} catch (FileNotFoundException e) {
				logger.error(e);
				throw ExceptionCommonBase.throwExceptionCommonBase(e);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} finally{
				if(pw!=null){
					pw.close();
				}
			}
		}
	}
	
	
	public void storeEfsInfoListToFile(List<EfsInfo> efsList, String filePath, Boolean append) throws ExceptionCommonBase{
		try {
			Thread.sleep(200);
		} catch (InterruptedException e1) {
			e1.printStackTrace();
			throw ExceptionCommonBase.throwExceptionCommonBase(e1);
		}
		PrintWriter pw = null;
		try {
			pw = new PrintWriter(new OutputStreamWriter(
					new FileOutputStream(filePath,append), "utf-8"));
				for(EfsInfo info : efsList){
					try {
						if(info.getEfs_type().matches("^(-1)?\\d+$")){
							int efsTypeNum = Utils.toInt(info.getEfs_type(), 0);
							pw.println(info.getEfs_id()+","+info.getEfs_type()+","+info.getFile_name()+","+
									ConstVar_EFS.DNS_HOST+FileUtils.getFilePath(FileUsedType.lookup(efsTypeNum), 
											info.getEfs_id(), info.getFile_name()));
						}else{
							//cms, activity
							pw.println(info.getEfs_id()+","+info.getEfs_type()+","+info.getFile_name()+","+
									ConstVar_EFS.DNS_HOST+info.getFile_name());
						}
						
					} catch (NoSuchAlgorithmException e) {
						e.printStackTrace();
						continue;
					}
				}
		} catch (FileNotFoundException e) {
			logger.error(e);
			throw ExceptionCommonBase.throwExceptionCommonBase(e);
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		} finally{
			if(pw!=null){
				pw.close();
			}
		}
	}

	public void fetchOkAndWriteBack(String filePath, EfsInfo efsInfo)
			throws ExceptionCommonBase {
			writeBackToFilePath(filePath,
					InputErrorFileAppendType.rewrite, efsInfo, -1);
	}
	
 	public void writeBackToFilePath(String path, InputErrorFileAppendType mode,
			EfsInfo efsInfo, int sth) throws ExceptionCommonBase {
 		synchronized (lock) {
 			List<EfsInfo> list = new ArrayList<EfsInfo>();
 			boolean append = true;
 			if(InputErrorFileAppendType.rewrite.equals(mode)){
 				list = getEfsInfosFromFile(path);
 				if(efsInfo!=null){
 					if(sth==-1){
 						list.remove(efsInfo);
 					}else if(sth==1){
 						list.add(efsInfo);
 					}
 				}
 				Set<EfsInfo> fetchSet = new HashSet<EfsInfo>(list);
 				list.clear();
 				list.addAll(fetchSet);
 				Collections.sort(list);
 				append = false;
 			}else if(InputErrorFileAppendType.append.equals(mode)){
 				list.add(efsInfo);
 				append = true;
 			}
 			storeEfsInfoListToFile(list, path, append);
		}
	}
	
//	private List<EfsInfo> initInputEfsInfos(String filePath) throws ExceptionCommonBase{
//		return getEfsInfosFromFile(filePath);
//	}
	
	public static List<EfsInfo> getEfsInfosFromFile(String filePath) throws ExceptionCommonBase{
		List<EfsInfo> efsInfos = new ArrayList<EfsInfo>();
		File file = new File(filePath);
		if(!file.exists()){
			return efsInfos;
		}
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(
					new FileInputStream(file),"utf-8"));
			String idStr = null;
			while((idStr=br.readLine())!=null){
				String[] strs = idStr.trim().split(",");
				if(strs.length==4 
						&& strs[0].matches("\\d+")){
					EfsInfo efsInfo = new EfsInfo(
							Long.parseLong(strs[0]), 
							strs[1],
							strs[2],EfsInfoFromType.fromFile);
					efsInfos.add(efsInfo);
				}
			}
		} catch (Exception e) {
			logger.error(e);
			throw ExceptionCommonBase.throwExceptionCommonBase(e);
		} finally{
			if(br!=null){
				try {
					br.close();
				} catch (IOException e) {
					logger.error(e);
					throw ExceptionCommonBase.throwExceptionCommonBase(e);
				}
			}
		}
		Set<EfsInfo> fetchSet = new HashSet<EfsInfo>(efsInfos);
		efsInfos.clear();
		efsInfos.addAll(fetchSet);
		Collections.sort(efsInfos);
		return efsInfos;
	}
	
	
	public boolean isFilesExists(List<String> filePathList){
		boolean exists = true;
		for(String filePath : filePathList){
			String localFilePath = ConstVar_EFS.UPLOAD_ADDRESS+filePath;
			File file = new File(localFilePath);
			long length;
			try {
				length = Util.getInputStreamLengthFromUrl(ConstVar_EFS.DNS_HOST + filePath);
			} catch (IOException e) {
				length = -1;
			}
			if(!file.exists() ||
					file.length()!=length){
				exists = false;
			}
		}
		return exists;
	}

	/**
	 * 判断线程对应的拉取文件是否为空
	 * @param filePath
	 * @return
	 */
	public boolean isFetchFileEmpty(String filePath) {
		return false;
	}
}
